#include "Keybord.h"

//global value:
osThreadId threadKeyboard_id;
enum KeyStroke KeyPress;
osThreadDef(threadKeyboard, osPriorityNormal, 1, 0); 




void initKeyboard()
{
		KeyPress=NotKeyPress;
		initPortInt();
		initI2C2();	
		initMAX7370();
		threadKeyboard_id= osThreadCreate(osThread(threadKeyboard), NULL);
}

void initPortInt()
{
		GPIO_PortClock(PORT_INT_KEY, ENABLE);
	  GPIO_PinConfigure(PORT_INT_KEY,PIN_INT_KEY,GPIO_MODE_INPUT ,GPIO_OUTPUT_PUSH_PULL, GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
}

void initI2C2()
{
		//*** подключение ножек I2C************************
				GPIO_PinAF (GPIOB,10,GPIO_AF_I2C2);
				GPIO_PinAF (GPIOB,11,GPIO_AF_I2C2);
				GPIO_PinConfigure(GPIOB,10,GPIO_MODE_AF ,GPIO_OUTPUT_OPEN_DRAIN, GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
				GPIO_PinConfigure(GPIOB,11,GPIO_MODE_AF ,GPIO_OUTPUT_OPEN_DRAIN, GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
	 //*****настройка модуля*****************************
				RCC->APB1ENR MSET_BIT22 ;  // подаём синхронизацию на i2c2
				I2C2->CR1 MRSET_BIT0; // выключаем переферию
				I2C2->CR2=0;
				I2C2->CCR=0;
				I2C2->TRISE=0x02;
				I2C2->CR2|=42;     // частота APB1=42 мгц
				I2C2->CCR|=150;		 // настройка делителя (1/42)*400=100 khz
				I2C2->TRISE|=40; // время выборки
				I2C2->CR1 MSET_BIT0; // включаем переферию		
}

void initMAX7370(void)
{
				//char i;
	 //**** настройка конфигурационного регистра********************
				I2C2->CR1 MSET_BIT8; // генерация сигнала старт
				while((I2C2->SR1 & 0x01)==0) {} // ожидаем выставления бита
				(void)I2C2->SR1;
				I2C2->DR =0x70; // адрес ведомого
				while((I2C2->SR1 & 0x02)==0) {} // передача адреса
				(void)I2C2->SR1;
				(void)I2C2->SR2;
				I2C2->DR =0x01; // конфигурационный регистр
				while((I2C2->SR1 & 0x04)==0) {} //байт передан
				I2C2->DR =0x83; //вывод из сна
				while((I2C2->SR1 & 0x04)==0) {} //байт передан
				I2C2->CR1 MSET_BIT9; // генерация сигнала стоп
	//**** настройка регистра прерываний*************************
				I2C2->CR1 MSET_BIT8; // генерация сигнала старт
	// I2C_GenerateSTART(I2C2,ENABLE);
				while((I2C2->SR1 & 0x01)==0) {} // ожидаем выставления бита
				(void)I2C2->SR1;
				I2C2->DR =0x70; // адрес ведомого
				while((I2C2->SR1 & 0x02)==0) {} // передача адреса
				(void)I2C2->SR1;
				(void)I2C2->SR2;
				I2C2->DR =0x03; // регистр прерываний****
				while((I2C2->SR1 & 0x04)==0) {} //байт передан
				I2C2->DR =0x04; //прерывание после 4 циклов
				while((I2C2->SR1 & 0x04)==0) {} //байт передан
				I2C2->CR1 MSET_BIT9; // генерация сигнала стоп						
  //*************************************************************	
}


void threadKeyboard(void const *argument){

	for (;;) 
	{
		osDelay(PERIOD_SCAN_KEYBOARD); // ожидание след опроса
		if (GPIO_PinRead(PORT_INT_KEY,PIN_INT_KEY)==0) // в буфере есть нажатые клавиши
		{
			while (KeyPress!=NotKeyPress){osThreadYield();} // ожидаем когда считают предыдущую нажатую клавишу
			KeyPress=readKodKeyPress();			
		}		
	}
}

enum KeyStroke readKodKeyPress(void)
{
			unsigned char i;
			enum KeyStroke key;
			I2C2->CR1 MSET_BIT8; // генерация сигнала старт
			while((I2C2->SR1 & 0x01)==0) {osThreadYield();} // ожидаем выставления бита
			i=I2C2->SR1;
			I2C2->DR =0x70; // адрес ведомого
			while((I2C2->SR1 & 0x02)==0) {osThreadYield();} // передача адреса
			i=I2C2->SR1;
			i=I2C2->SR2;
			I2C2->DR =0x00; // буфер кода клавиатуры
			while((I2C2->SR1 & 0x04)==0) {osThreadYield();} //байт передан
			I2C2->CR1 MSET_BIT8; // повторный старт
			while((I2C2->SR1 & 0x01)==0) {osThreadYield();} // ожидаем выставления бита		
			i=I2C2->SR1;
			I2C2->DR =0x71; // адрес ведомого + чтение
			while((I2C2->SR1 & 0x02)==0) {osThreadYield();} // передача адреса
			i=I2C2->SR1;
			i=I2C2->SR2;	
			while((I2C2->SR1 & 0x40)==0) {osThreadYield();} // прием данных	
			i=I2C2->DR;
			key=(enum KeyStroke)(i & (~0xc0)); // маскируем 2 старших бита
			I2C2->CR1 MSET_BIT9; // генерация сигнала стоп
			return(key);
}


enum KeyStroke waitKeyStroke(void)
{
	enum KeyStroke key;
	while(KeyPress==NotKeyPress) // ждём нажатия клавиши
		{
			osThreadYield();
		}
	key=KeyPress;
	KeyPress=NotKeyPress;	
	return(key);		
}

